# -*- coding: utf-8 -*-

# Copyright (c) 2025 Lijiang
# Licensed under the MIT License
# See LICENSE file for details

"""
多线程池管理器，用于管理多个视频压缩任务
"""

import threading
import time
import logging
from typing import List, Optional, Callable
from PyQt6.QtCore import QObject, pyqtSignal
from .ffmpeg_compressor import FFmpegCompressionWorker

logger = logging.getLogger(__name__)


class ThreadPoolManager(QObject):
    """多线程池管理器"""
    
    ############################### 信号定义 ###############################
    all_tasks_finished = pyqtSignal()  # 所有任务完成信号
    task_started = pyqtSignal(str)     # 任务开始信号 (文件路径)
    task_finished = pyqtSignal(str, bool, str)  # 任务完成信号 (文件路径, 成功, 消息)
    
    def __init__(self, max_workers: int = 2):
        super().__init__()
        self.max_workers = max_workers
        self.active_workers: List[FFmpegCompressionWorker] = []
        self.pending_tasks: List[dict] = []
        self.running_tasks: List[dict] = []
        self.completed_tasks: List[dict] = []
        self.lock = threading.Lock()
        self.is_running = False
        
    def add_task(self, input_path: str, output_path: str, compression_ratio: float,
                 progress_callback: Optional[Callable] = None,
                 status_callback: Optional[Callable] = None,
                 finished_callback: Optional[Callable] = None,
                 file_info_callback: Optional[Callable] = None) -> str:
        """添加压缩任务到队列"""
        task_id = f"{input_path}_{int(time.time())}"
        
        task = {
            'id': task_id,
            'input_path': input_path,
            'output_path': output_path,
            'compression_ratio': compression_ratio,
            'progress_callback': progress_callback,
            'status_callback': status_callback,
            'finished_callback': finished_callback,
            'file_info_callback': file_info_callback,
            'status': 'pending'
        }
        
        with self.lock:
            self.pending_tasks.append(task)
        
        # 尝试启动任务
        self._try_start_next_task()
        
        return task_id
    
    def _try_start_next_task(self):
        """尝试启动下一个待处理的任务"""
        with self.lock:
            if len(self.active_workers) >= self.max_workers:
                return
            
            if not self.pending_tasks:
                return
            
            ############################### 获取下一个任务 ###############################
            task = self.pending_tasks.pop(0)
            task['status'] = 'running'
            
            ############################### 将任务添加到运行中任务列表 ###############################
            self.running_tasks.append(task)
            
            ############################### 创建压缩工作线程 ###############################
            from .ffmpeg_compressor import FFmpegCompressionWorker
            worker = FFmpegCompressionWorker(
                task['input_path'],
                task['output_path'],
                task['compression_ratio']
            )
            
            ############################### 连接信号 ###############################
            if task['progress_callback']:
                worker.progress_updated.connect(task['progress_callback'])
            if task['status_callback']:
                worker.status_updated.connect(task['status_callback'])
            if task['file_info_callback']:
                worker.file_info_updated.connect(task['file_info_callback'])
            
            ############################### 连接内部信号处理 ###############################
            task_id = task['id']  # 创建局部变量避免闭包问题
            worker.compression_finished.connect(
                lambda success, message, tid=task_id: self._on_task_finished(tid, success, message)
            )
            
            ############################### 启动工作线程 ###############################
            worker.start()
            self.active_workers.append(worker)
            
            ############################### 发送任务开始信号 ###############################
            self.task_started.emit(task['input_path'])
    
    def _on_task_finished(self, task_id: str, success: bool, message: str):
        """任务完成回调"""
        print(f"[ThreadPool] _on_task_finished被调用: task_id={task_id}, success={success}, message={message}")
        with self.lock:
            ############################### 从活跃工作线程中移除 ###############################
            worker_to_remove = None
            for worker in self.active_workers:
                if hasattr(worker, 'task_id') and worker.task_id == task_id:
                    worker_to_remove = worker
                    break
            
            if worker_to_remove:
                self.active_workers.remove(worker_to_remove)
            
            ############################### 从运行中任务列表查找并更新任务状态 ###############################
            task_found = False
            for task in self.running_tasks[:]:
                if task['id'] == task_id:
                    print(f"[ThreadPool] 找到运行中的任务，准备移动到completed: {task_id}")
                    task['status'] = 'completed' if success else 'failed'
                    task['success'] = success
                    task['message'] = message
                    ############################### 移动到已完成任务列表 ###############################
                    self.running_tasks.remove(task)
                    self.completed_tasks.append(task)
                    print(f"[ThreadPool] 任务已移动到completed_tasks，当前completed_tasks数量: {len(self.completed_tasks)}")
                    task_found = True
                    break
            
            if not task_found:
                print(f"[ThreadPool] 警告：未找到运行中的任务: {task_id}")
                print(f"[ThreadPool] 当前running_tasks数量: {len(self.running_tasks)}")
                print(f"[ThreadPool] 当前pending_tasks数量: {len(self.pending_tasks)}")
                print(f"[ThreadPool] 当前completed_tasks数量: {len(self.completed_tasks)}")
        
        ############################### 发送任务完成信号 ###############################
        task_info = self.get_task_info(task_id)
        if task_info:
            self.task_finished.emit(task_info['input_path'], success, message)
            
            ############################### 调用用户提供的finished_callback ###############################
            if task_info.get('finished_callback'):
                print(f"[ThreadPool] 调用finished_callback: success={success}, message={message}")
                try:
                    task_info['finished_callback'](success, message)
                    print(f"[ThreadPool] finished_callback调用成功")
                except Exception as e:
                    print(f"[ThreadPool] 调用finished_callback时发生错误: {e}")
                    logger.error(f"调用finished_callback时发生错误: {e}")
            else:
                print(f"[ThreadPool] 没有找到finished_callback")
        
        ############################### 尝试启动下一个任务 ###############################
        self._try_start_next_task()
        
        ############################### 检查是否所有任务都完成了 ###############################
        with self.lock:
            if not self.pending_tasks and not self.active_workers:
                self.all_tasks_finished.emit()
    
    def get_task_info(self, task_id: str) -> Optional[dict]:
        """获取任务信息"""
        with self.lock:
            print(f"[ThreadPool] 查找任务信息: {task_id}")
            print(f"[ThreadPool] pending_tasks数量: {len(self.pending_tasks)}")
            print(f"[ThreadPool] running_tasks数量: {len(self.running_tasks)}")
            print(f"[ThreadPool] completed_tasks数量: {len(self.completed_tasks)}")
            
            ############################### 打印所有任务的ID用于对比 ###############################
            all_tasks = self.pending_tasks + self.running_tasks + self.completed_tasks
            print(f"[ThreadPool] 所有任务ID: {[task['id'] for task in all_tasks]}")
            
            for task in all_tasks:
                if task['id'] == task_id:
                    print(f"[ThreadPool] 找到任务信息: {task_id}, finished_callback存在: {'finished_callback' in task}")
                    return task
        print(f"[ThreadPool] 未找到任务信息: {task_id}")
        return None
    
    def get_active_tasks(self) -> List[dict]:
        """获取活跃任务列表"""
        with self.lock:
            return [task for task in self.pending_tasks + self.completed_tasks 
                   if task['status'] == 'running']
    
    def get_pending_tasks(self) -> List[dict]:
        """获取待处理任务列表"""
        with self.lock:
            return [task for task in self.pending_tasks if task['status'] == 'pending']
    
    def get_completed_tasks(self) -> List[dict]:
        """获取已完成任务列表"""
        with self.lock:
            return [task for task in self.completed_tasks]
    
    def cancel_task(self, task_id: str) -> bool:
        """取消指定任务"""
        with self.lock:
            ############################### 查找活跃工作线程 ###############################
            for worker in self.active_workers:
                if hasattr(worker, 'task_id') and worker.task_id == task_id:
                    worker.cancel()
                    return True
            
            ############################### 查找待处理任务 ###############################
            for task in self.pending_tasks:
                if task['id'] == task_id:
                    task['status'] = 'cancelled'
                    self.pending_tasks.remove(task)
                    return True
        
        return False
    
    def cancel_all_tasks(self):
        """取消所有任务"""
        with self.lock:
            ############################### 取消所有活跃工作线程 ###############################
            for worker in self.active_workers:
                worker.cancel()
            
            ############################### 清空待处理任务 ###############################
            for task in self.pending_tasks:
                task['status'] = 'cancelled'
            
            self.pending_tasks.clear()
    
    def pause_all_tasks(self):
        """暂停所有任务（实际上取消当前任务，待处理任务保持待处理状态）"""
        with self.lock:
            ############################### 取消所有活跃工作线程 ###############################
            for worker in self.active_workers:
                worker.cancel()
    
    def resume_tasks(self):
        """恢复任务处理"""
        self._try_start_next_task()
    
    def get_queue_status(self) -> dict:
        """获取队列状态"""
        with self.lock:
            return {
                'active_count': len(self.active_workers),
                'pending_count': len(self.pending_tasks),
                'completed_count': len(self.completed_tasks),
                'max_workers': self.max_workers
            }
    
    def clear_completed_tasks(self):
        """清理已完成的任务"""
        with self.lock:
            self.completed_tasks.clear()
    
    def set_max_workers(self, max_workers: int):
        """设置最大工作线程数"""
        with self.lock:
            self.max_workers = max_workers
            
            ############################### 如果当前活跃线程数超过新的最大值，需要等待一些任务完成 ###############################
            if len(self.active_workers) > max_workers:
                ############################### 这里可以添加逻辑来优雅地停止多余的线程 ###############################
                pass
